package com.fangngng.pushall.controller;

import com.fangngng.pushall.constant.ErrorCode;
import com.fangngng.pushall.dto.LoginReqDto;
import com.fangngng.pushall.dto.RegisterVO;
import com.fangngng.pushall.dto.Result;
import com.fangngng.pushall.entity.User;
import com.fangngng.pushall.exception.BusinessException;
import com.fangngng.pushall.service.LoginService;
import com.fangngng.pushall.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @author fei.fang
 * @date 2021/4/2
 **/
@Slf4j
@RestController
public class LoginController {

    @Autowired
    private LoginService loginService;

    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    public LoginController(AuthenticationManagerBuilder authenticationManagerBuilder) {
        this.authenticationManagerBuilder = authenticationManagerBuilder;
    }

    /**
     * 登录
     * @param loginReqDto
     * @return
     */
    @PostMapping("/login")
    public Result<String> login(@RequestBody LoginReqDto loginReqDto){
        // 登陆验证
        String userName = loginReqDto.getUserName();
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userName, loginReqDto.getPassword());
        Authentication authentication = null;
        try {
            authentication = authenticationManagerBuilder.getObject().authenticate(token);
        } catch (AuthenticationException e) {
            log.warn("{}:登录失败", userName);
            return new Result<>(ErrorCode.ERROR_LOGIN_USER_PASSWORD_NOT_CORRECT);
        }
        SecurityContextHolder.getContext().setAuthentication(authentication);

        //创建jwt信息
        // todo rememberMe
        String jwtToken = loginService.getJwtToken(userName, true);
        return Result.ok(jwtToken);
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        //加密
        String newPassword = passwordEncoder.encode("123456");
        System.out.println(newPassword);
    }

    /**
     * 注册
     * @param request
     * @param registerVO
     * @return
     */
    @PostMapping("/register")
    public Result<String> register(HttpServletRequest request, @RequestBody RegisterVO registerVO){
        log.info("注册, ip:{}", IpUtil.getIpAddress(request));

        if(StringUtils.isBlank(registerVO.getEmail()) || StringUtils.isBlank(registerVO.getPassword())
            || StringUtils.isBlank(registerVO.getNickName())){
            log.warn("入參错误");
            throw new BusinessException(ErrorCode.ERROR_PARAM_ERROR);
        }

        Result<User> register = loginService.register(registerVO.getEmail(), registerVO.getPassword(),
                registerVO.getValidateCode(), registerVO.getNickName());
        if (register.isFail()) {
            return new Result<>(register.getCode(), register.getMessage());
        }
        // 获取jwt
        //创建jwt信息
        // todo rememberMe
        String jwtToken = loginService.getJwtToken(register.getData().getName(), true);
        return Result.ok(jwtToken);
    }

    @GetMapping("/role")
    @PreAuthorize("hasAnyAuthority('bxsheng')")
    public String roleInfo(){
        return "需要获得bxsheng权限，才可以访问";
    }

    @GetMapping("/roles")
    @PreAuthorize("isAuthenticated()")
    public String rolekdream(){
        return "需要获得kdream权限，才可以访问";
    }
}
